package com.cn.qtms.util;

/**********************************************************************
 * FILE : DateUtils.java
 * CREATE DATE : 2008-12-10
 * DESCRIPTION :
 *
 *
 * CHANGE HISTORY LOG
 *---------------------------------------------------------------------
 * NO.|    DATE    |     NAME     |     REASON     | DESCRIPTION
 *---------------------------------------------------------------------
 * 1  | 2008-06-06 |  ZhangGuojie  |    创建草稿版本
 * 2  | 2011-09-05 |  yangzhi     |    新增方法:addMilliseconds(Date date, long amount)
 * 3  | 2012-11-23 |  yangzhi     |    新增方法:getFirstDayOfWeek,取得指定日期所在周的第一天;addWeekDayOfWeek,在指定的日期上+指定的周
 *---------------------------------------------------------------------              
 ******************************************************************************/

import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale;
/**
 * @author User
 */
public class DateUtils {
    /**
     * Default locale is CHINA
     */
    public static final Locale DEFAULT_LOCALE = Locale.CHINA;

    public final static String FORMAT_DATE_DEFAULT = "yyyy-MM-dd HH:mm:ss";

    public final static String FORMAT_DATE_YYYYMMDD = "yyyyMMdd";

    public final static String FORMAT_DATE_YYYY_MM_DD = "yyyy-MM-dd";

    public final static String FORMAT_DATE_PATTERN_1 = "yyyy/MM/dd";

    public final static String FORMAT_DATE_PATTERN_2 = "yyyy/M/dd";

    public final static String FORMAT_DATE_PATTERN_3 = "yyyy/MM/d";

    public final static String FORMAT_DATE_PATTERN_4 = "yyyy/M/d";

    public final static String FORMAT_DATE_YYYY_MM_DD_HHMMSS = "yyyyMMddHHmmss";

    public final static String FORMAT_DATE_YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";

    public final static String FORMAT_DATE_YYYY_MM_DD_HH_MM_SS2 = "yyyy/MM/dd HH:mm:ss";

    public final static String FORMAT_DATE_YYYY_MM_DD_HHMM = "yyyy-MM-dd HHmm";

    public final static String FORMAT_DATE_YYYY_MM_DD_HH_MM = "yyyy-MM-dd HH:mm";

    public final static String FORMAT_DATE_HH_MM = "HH:mm";

    public final static String FORMAT_DATE_HH_MM_SS = "HH:mm:ss";

    public final static String FORMAT_DATE_HHMM = "HHmm";

    public final static String FORMAT_DATE_HHMMSS = "HHmmss";

    public static final String FORMAT_DATE_YYMMDD = "yyMMdd";

    public static final String FORMAT_WORK_TIME = "yyyy-MM-dd HHmmss";

    public static final String FORMAT_DATE_YYYY_MM_DDHHMMSS = "yyyy-MM-ddHHmmss";

    public static final String FORMAT_DATE_YYYYMMDD_BLANK_HHMMSS = "yyyyMMdd HH:mm:ss";

    public static final String FORMAT_DATE_YYMMDDHHMMSSSSS = "yyMMddHHmmssSSS";

    public final static String FORMAT_DATE_MM_DD_HH_MM = "MM-dd HH:mm";

    public final static String FORMAT_DATE_MM_DD_HH_MM_SS = "MM/dd HH:mm:ss";

    public static final String FORMAT_DATE_YYYY_MM_DD_HH_MM_SS_SSS = "yyyy-MM-dd HH:mm:ss.SSS";

    public static final String FORMAT_DATE_YYYYMM = "yyyy-MM";

    public final static int compareDate(String stringValue1, String stringValue2) throws ParseException {
        Date date1 = tryParse(stringValue1);
        if (date1 == null){
            throw new ParseException("Can not parse " + stringValue1 + " to Date.", 0);
        }
        Date date2 = tryParse(stringValue2);
        if (date2 == null){
            throw new ParseException("Can not parse " + stringValue1 + " to Date.", 0);
        }
        return date1.compareTo(date2);
    }

    /**
     * 给定时间于当期时间的比较，差值为分钟
     */
    public final static long compareDateToMin(String stringValue1) throws ParseException {

        SimpleDateFormat df = new SimpleDateFormat(FORMAT_DATE_YYYY_MM_DD_HH_MM_SS);
        Date now = Calendar.getInstance().getTime();
        Date date = df.parse(stringValue1);
        long l = now.getTime() - date.getTime();

        return l / (60 * 1000);

    }

    /**
     * 转换时间格式  yyyy/MM/dd HH:mm:ss
     * @return
     */
    public final static String getCurrentDateAsString() {
        return getCurrentDateAsString(FORMAT_DATE_DEFAULT);
    }

    /**
     * 将当前时间转换时间格式 yyyy/MM/dd HH:mm:ss
     * @param formatPattern 格式转换器
     * @return
     */
    public final static String getCurrentDateAsString(String formatPattern) {
        Date date = getCurrentDate();
        return format(date, formatPattern);
    }

    /**
     * 获取当前日期
     * @return
     */
    public final static Date getCurrentDate() {
        return Calendar.getInstance().getTime();
    }


    /**
     * 指定日期时间格式转换 yyyy/MM/dd HH:mm:ss
     * @param date
     * @return
     */
    public final static String format(Date date) {
        if (date == null) {
            return "";
        }
        return format(date, FORMAT_DATE_DEFAULT);
    }

    /**
     * 指定日期格式转换 yyyy-MM-dd HH:mm:ss
     * @param date
     * @return
     */
    public final static String formatDateTime(Date date) {
        if (date == null) {
            return "";
        }
        return format(date, FORMAT_DATE_YYYY_MM_DD_HH_MM_SS);
    }

    /**
     * 日期转timeStamp
     * @param date
     * @return
     */
    public final static String formatTimestamp(Date date) {
        if (date == null) {
            return "";
        }
        return format(date, FORMAT_DATE_YYYY_MM_DD_HH_MM_SS_SSS);
    }

    /**
     * date转timeStamp
     * @param date
     * @return
     */
    public final static Date parseTimestamp(String date) {
        if (date == null) {
            return null;
        }
        return parse(date, FORMAT_DATE_YYYY_MM_DD_HH_MM_SS_SSS);
    }

    /**
     * date转yyyy-MM-dd HH:mm:ss
     * @param date
     * @return
     */
    public final static Date parseDate(String date) {
        if (date == null) {
            return null;
        }
        return parse(date, FORMAT_DATE_YYYY_MM_DD_HH_MM_SS);
    }

    /**
     * 根据时间格式转换时间
     * @param date
     * @param formatPattern
     * @return
     */
    public final static String format(Date date, String formatPattern) {
        if (date == null) {
            return "";
        }
        return new SimpleDateFormat(formatPattern).format(date);
    }

    /**
     * 时间格式转换 yyyy/MM/dd HH:mm:ss
     * @param stringValue
     * @return
     */
    public final static Date parse(String stringValue) {
        return parse(stringValue, FORMAT_DATE_DEFAULT);
    }

    /**
     * Parse string value to Date with given format pattern.
     *
     * @param stringValue   date value as string.
     * @param formatPattern format pattern.
     * @return Date represents stringValue, null while parse exception occurred.
     * @see #FORMAT_DATE_DEFAULT
     */
    public final static Date parse(String stringValue, String formatPattern) {
        SimpleDateFormat format = new SimpleDateFormat(formatPattern);
        try {
            return format.parse(stringValue);
        } catch (ParseException e) {
            return null;
        }
    }

    /**
     * 时间戳各个格式的时间匹配 最后全部转为Date
     * @param o
     * @return
     */
    public final static Date tryParse(Object o){
        if (o == null) {
            return null;
        }
        if (o instanceof Date) {
            return (Date) o;
        }
        if (o instanceof java.sql.Date) {
            return (Date) o;
        }
        if (o instanceof String) {
            // yyyy-MM-dd HH:mm:ss  /
            String d=(String) o;
            StringBuilder format=new StringBuilder("yyyy");
            if (d.charAt(4)=='-') {
                format.append("-MM-dd");
            }else if(d.charAt(4)=='/') {
                format.append("/MM/dd");
            }else if (d.charAt(4)=='_'){
                format.append("_MM_dd");
            }else {
                format.append("MMdd");
            }
            if (d.length()<format.length()) {
                return null;
            }else if (d.length()==format.length()) {
                return parse(d, format.toString());
            }
            if (d.charAt(format.length())==' ') {
                format.append(' ');
            }
            if (d.charAt(format.length()+2)==':') {
                format.append("HH:mm:ss");
            }else if (d.charAt(format.length()+2)=='/') {
                format.append("HH/mm/ss");
            }else {
                format.append("HHmmss");
            }
            if (d.length()<format.length()) {
                return null;
            }
            if (d.length()==format.length()) {
                return parse(d,format.toString());
            }
            if (d.charAt(format.length())=='.'&&d.length()==(format.length()+4)) {
                format.append(".SSS");
            }else if(d.length()==(format.length()+3)){
                format.append("SSS");
            }else {
                d=d.substring(0, format.length());
            }
            return parse(d, format.toString());
        }
        if (o instanceof Long) {
            long l=(long) o;
            if (l< 10000000000L) {
                return new Date(l*1000);
            }
            return new Date(l);
        }
        if (o instanceof Integer) {
            long l=(int)o*1000;
            return new Date(l);
        }
        return null;
    }


    public static Timestamp parseTimestamp(String stringValue, String formatPattern) {
        return new Timestamp(parse(stringValue, formatPattern).getTime());
    }

    public static Timestamp parseTimestamp(Date d) {
        return new Timestamp(d.getTime());
    }

    /**
     * 指定时间加上毫秒数
     * @param date
     * @param amount
     * @return
     */
    public static Date addMilliseconds(Date date, int amount) {
        return add(date, Calendar.MILLISECOND, amount);
    }

    /**
     * 指定时间加上毫秒数
     * @param date
     * @param amount
     * @return
     */
    public static Date addMilliseconds(Date date, long amount) {
        if (date == null) {
            throw new IllegalArgumentException("The date must not be null");
        }
        Calendar c = Calendar.getInstance();
        c.setTimeInMillis(date.getTime() + amount);
        return c.getTime();
    }

    /**
     * 指定时间加上分钟数
     * @param date
     * @param amount
     * @return
     */
    public static Date addMinutes(Date date, int amount) {
        return add(date, Calendar.MINUTE, amount);
    }

    /**
     * 指定时间加上指定数量(amount 数量,calendarField 单位)
     * @param date
     * @param calendarField
     * @param amount
     * @return
     */
    public static Date add(Date date, int calendarField, int amount) {
        if (date == null) {
            throw new IllegalArgumentException("The date must not be null");
        }
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(calendarField, amount);
        return c.getTime();
    }

    //获取指定时间 n周后的时间
    /**
     * 获取两个时间的时间区间
     *
     * @param currentDate 指定时间
     * @param week 周数
     * @return
     */
    public static Date addWeekDayOfWeek(Date currentDate, int week) {
        Calendar c = new GregorianCalendar();
        c.setTime(currentDate);
        c.add(Calendar.WEEK_OF_YEAR, week);
        return c.getTime();
    }

    //获取两个时间的时间差
    /**
     * 获取两个时间的时间区间
     *
     * @param startDate 开始时间
     * @param endDate 结束时间
     * @return
     */
    public static Integer getTwoDate(Date startDate, Date endDate) {
        if (startDate == null || endDate == null) {
            throw new IllegalArgumentException("The date must not be null");
        }
        return (int) (endDate.getTime() - startDate.getTime()) / (1000 * 60 * 60 * 24);
    }

    /**
     * 判断两个日期区间 小于指定的days
     *
     * @param startDate
     * @param endDate
     * @param days 指定的天数
     * @return
     */
    public static boolean isRankDay(Date startDate, Date endDate, int days) {
        if (startDate == null || endDate == null) {
            throw new IllegalArgumentException("The date must not be null");
        }
        return (endDate.getTime() - startDate.getTime()) / (1000 * 60 * 60 * 24) <= days;
    }

    /**
     * 计算两个时间之间相差几分钟
     *
     * @param startDate 被减时间
     * @param endDate   减时间
     * @return
     */
    public static Long getTwoDateMinutes(Date endDate, Date startDate) {
        if (startDate == null || endDate == null) {
            throw new IllegalArgumentException("The date must not be null");
        }
        return (endDate.getTime() - startDate.getTime()) / (1000 * 60);
    }

    /**
     * 转化时间格式
     *
     * @param srcTimeStr 需要转换的时间
     * @param srcTimePattern 转换前时间格式
     * @param desTimePattern    转换后时间格式
     * @return
     */
    public static String parseTimeStr(String srcTimeStr, String srcTimePattern, String desTimePattern) {
        return format(parse(srcTimeStr, srcTimePattern), desTimePattern);
    }

    /**
     * 获取今日0点
     * @return
     */
    public static Date getTodayBegin() {
        return getBeginOfDay(new Date());
    }

    /**
     * 获取每月头一天
     * @return
     */
    public static Date getMonthBegin() {
        Calendar c = Calendar.getInstance();
        c.set(Calendar.DAY_OF_MONTH,1);
        c.set(Calendar.HOUR_OF_DAY, 0);
        c.set(Calendar.MINUTE, 0);
        c.set(Calendar.SECOND, 0);
        return c.getTime();
    }

    /**
     * 前i天
     * @param date
     * @param i
     * @return
     */
    public static Date before(Date date, int i) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DAY_OF_MONTH, -1 * i);
        return calendar.getTime();
    }

    /**
     * 获取某天的0点
     * @param day
     * @return
     */
    public static Date getBeginOfDay(Date day) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(day);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        Date zero = calendar.getTime();
        return zero;
    }

    /**
     * 获取某天23：59：59
     * @param day
     * @return
     */
    public static Date getEndOfDay(Date day) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(day);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        Date zero = calendar.getTime();
        return zero;
    }
}